home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-ARM / UACCESS.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  5KB  |  198 lines

  1. #ifndef _ASMARM_UACCESS_H
  2. #define _ASMARM_UACCESS_H
  3.  
  4. /*
  5.  * User space memory access functions
  6.  */
  7. #include <linux/sched.h>
  8.  
  9. #define VERIFY_READ 0
  10. #define VERIFY_WRITE 1
  11.  
  12. /*
  13.  * The exception table consists of pairs of addresses: the first is the
  14.  * address of an instruction that is allowed to fault, and the second is
  15.  * the address at which the program should continue.  No registers are
  16.  * modified, so it is entirely up to the continuation code to figure out
  17.  * what to do.
  18.  *
  19.  * All the routines below use bits of fixup code that are out of line
  20.  * with the main instruction path.  This means when everything is well,
  21.  * we don't even have to jump over them.  Further, they do not intrude
  22.  * on our cache or tlb entries.
  23.  */
  24.  
  25. struct exception_table_entry
  26. {
  27.     unsigned long insn, fixup;
  28. };
  29.  
  30. /* Returns 0 if exception not found and fixup otherwise.  */
  31. extern unsigned long search_exception_table(unsigned long);
  32.  
  33. #include <asm/proc/uaccess.h>
  34.  
  35. extern inline int verify_area(int type, const void * addr, unsigned long size)
  36. {
  37.     return access_ok(type,addr,size) ? 0 : -EFAULT;
  38. }
  39.  
  40. /*
  41.  * Single-value transfer routines.  They automatically use the right
  42.  * size if we just have the right pointer type.
  43.  *
  44.  * The "__xxx" versions of the user access functions do not verify the
  45.  * address space - it must have been done previously with a separate
  46.  * "access_ok()" call.
  47.  *
  48.  * The "xxx_ret" versions return constant specified in the third
  49.  * argument if something bad happens.
  50.  */
  51. #define get_user(x,p)        __get_user_check((x),(p),sizeof(*(p)))
  52. #define __get_user(x,p)        __get_user_nocheck((x),(p),sizeof(*(p)))
  53. #define get_user_ret(x,p,r)    ({ if (get_user(x,p)) return r; })
  54. #define __get_user_ret(x,p,r)    ({ if (__get_user(x,p)) return r; })
  55.  
  56. #define put_user(x,p)        __put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
  57. #define __put_user(x,p)        __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
  58. #define put_user_ret(x,p,r)    ({ if (put_user(x,p)) return r; })
  59. #define __put_user_ret(x,p,r)    ({ if (__put_user(x,p)) return r; })
  60.  
  61. static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
  62. {
  63.     char *end = (char *)to + n;
  64.     if (access_ok(VERIFY_READ, from, n)) {
  65.         __do_copy_from_user(to, from, n);
  66.         if (n) memset(end - n, 0, n);
  67.     }
  68.     return n;
  69. }
  70.  
  71. static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
  72. {
  73.     __do_copy_from_user(to, from, n);
  74.     return n;
  75. }
  76.  
  77. #define copy_from_user_ret(t,f,n,r)                    \
  78.     ({ if (copy_from_user(t,f,n)) return r; })
  79.  
  80. static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
  81. {
  82.     if (access_ok(VERIFY_WRITE, to, n))
  83.         __do_copy_to_user(to, from, n);
  84.     return n;
  85. }
  86.  
  87. static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
  88. {
  89.     __do_copy_to_user(to, from, n);
  90.     return n;
  91. }
  92.  
  93. #define copy_to_user_ret(t,f,n,r)                    \
  94.     ({ if (copy_to_user(t,f,n)) return r; })
  95.  
  96. static __inline__ unsigned long clear_user (void *to, unsigned long n)
  97. {
  98.     if (access_ok(VERIFY_WRITE, to, n))
  99.         __do_clear_user(to, n);
  100.     return n;
  101. }
  102.  
  103. static __inline__ unsigned long __clear_user (void *to, unsigned long n)
  104. {
  105.     __do_clear_user(to, n);
  106.     return n;
  107. }
  108.  
  109. static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
  110. {
  111.     long res = -EFAULT;
  112.     if (access_ok(VERIFY_READ, src, 1))
  113.         __do_strncpy_from_user(dst, src, count, res);
  114.     return res;
  115. }
  116.  
  117. static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
  118. {
  119.     long res;
  120.     __do_strncpy_from_user(dst, src, count, res);
  121.     return res;
  122. }
  123.  
  124. extern __inline__ long strlen_user (const char *s)
  125. {
  126.     unsigned long res = 0;
  127.  
  128.     if (__addr_ok(s))
  129.         __do_strlen_user (s, res);
  130.  
  131.     return res;
  132. }
  133.  
  134. /*
  135.  * These are the work horses of the get/put_user functions
  136.  */
  137. #define __get_user_check(x,ptr,size)                    \
  138. ({                                    \
  139.     long __gu_err = -EFAULT, __gu_val = 0;                \
  140.     const __typeof__(*(ptr)) *__gu_addr = (ptr);            \
  141.     if (access_ok(VERIFY_READ,__gu_addr,size))            \
  142.         __get_user_size(__gu_val,__gu_addr,(size),__gu_err);    \
  143.     (x) = (__typeof__(*(ptr)))__gu_val;                \
  144.     __gu_err;                            \
  145. })
  146.  
  147. #define __get_user_nocheck(x,ptr,size)                    \
  148. ({                                    \
  149.     long __gu_err = 0, __gu_val = 0;                \
  150.     __get_user_size(__gu_val,(ptr),(size),__gu_err);        \
  151.     (x) = (__typeof__(*(ptr)))__gu_val;                \
  152.     __gu_err;                            \
  153. })
  154.  
  155. #define __put_user_check(x,ptr,size)                    \
  156. ({                                    \
  157.     long __pu_err = -EFAULT;                    \
  158.     __typeof__(*(ptr)) *__pu_addr = (ptr);                \
  159.     if (access_ok(VERIFY_WRITE,__pu_addr,size))            \
  160.         __put_user_size((x),__pu_addr,(size),__pu_err);        \
  161.     __pu_err;                            \
  162. })
  163.  
  164. #define __put_user_nocheck(x,ptr,size)                    \
  165. ({                                    \
  166.     long __pu_err = 0;                        \
  167.     __put_user_size((x),(ptr),(size),__pu_err);            \
  168.     __pu_err;                            \
  169. })
  170.  
  171. extern long __get_user_bad(void);
  172.  
  173. #define __get_user_size(x,ptr,size,retval)                \
  174. do {                                    \
  175.     retval = 0;                            \
  176.     switch (size) {                            \
  177.     case 1:    __get_user_asm_byte(x,ptr,retval);    break;        \
  178.     case 2:    __get_user_asm_half(x,ptr,retval);    break;        \
  179.     case 4:    __get_user_asm_word(x,ptr,retval);    break;        \
  180.     default: (x) = __get_user_bad();                \
  181.     }                                \
  182. } while (0)
  183.  
  184. extern long __put_user_bad(void);
  185.  
  186. #define __put_user_size(x,ptr,size,retval)                \
  187. do {                                    \
  188.     retval = 0;                            \
  189.     switch (size) {                            \
  190.     case 1: __put_user_asm_byte(x,ptr,retval);    break;        \
  191.     case 2: __put_user_asm_half(x,ptr,retval);    break;        \
  192.     case 4: __put_user_asm_word(x,ptr,retval);    break;        \
  193.     default: __put_user_bad();                    \
  194.     }                                \
  195. } while (0)
  196.  
  197. #endif /* _ASMARM_UACCESS_H */
  198.